/*	$Id: pkt.h 7 2008-07-29 02:58:11Z phrakt $	*/
/*
 * Copyright (c) 2003 Jean-Francois Brousseau <jfb@openbsd.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */


#ifndef _PFORGE_PKT_H_
#define _PFORGE_PKT_H_

#include <sys/types.h>
#include <sys/time.h>

#include <pforge/pbuf.h>
#include <pforge/queue.h>


#define PFPKT_NAME_MAXLEN      16
#define PFPKT_FIELD_MAXLEN     16


#define PFPKT_FLD_BIT		1
#define PFPKT_FLD_BYTE		2     /* single byte value */
#define PFPKT_FLD_SHORT		3     /* 16-bit value */
#define PFPKT_FLD_DOUBLE	4     /* 32-bit value */
#define PFPKT_FLD_QUAD		5     /* 64-bit value */
#define PFPKT_FLD_BINSTR	6     /* binary string of arbitrary length */
#define PFPKT_FLD_ASCIISTR	7   /* ASCII string (printable) */


#define PFPKT_CHAIN(p, n)           \
	do {                        \
		p->pkt_next = n;    \
		n->pkt_prev = p;    \
	} while (0)


#define PFPKT_HEAD(p) (p->pkt_buf == NULL ? NULL : p->pkt_buf->pb_hdr.pb_start)


typedef struct pf_expr PF_EXPR;

struct pf_pkt_tag {
	int     pt_off;
	int     pt_proto;
	void   *pt_data;
	TAILQ_ENTRY(pf_pkt_tag) pt_link;
};

typedef struct pf_pkt {
	unsigned int    pkt_len;	/* total size in bytes */
	unsigned int    pkt_off;	/* current offset */
	int             pkt_flags;
	int             pkt_if;		/* associated interface */
	struct timespec pkt_ts;		/* timestamp */

	PF_PCHAIN       pkt_bufs;

	TAILQ_HEAD(, pf_pkt_tag) pkt_tags;
	TAILQ_ENTRY(pf_pkt)      pkt_link;	/* link in packet chains */
} PF_PKT;


typedef TAILQ_HEAD(pf_pkt_q, pf_pkt) PF_PKTQ;




PF_PKT*  pf_pkt_alloc   (void);
PF_PKT*  pf_pkt_clone   (PF_PKT *);
void     pf_pkt_free    (void *);
int      pf_pkt_clear   (PF_PKT *);
int      pf_pkt_set     (PF_PKT *, const void *, size_t);
int      pf_pkt_prepend (PF_PKT *, const void *, size_t);
int      pf_pkt_append  (PF_PKT *, const void *, size_t);
ssize_t  pf_pkt_copy    (const PF_PKT *, void *, size_t, size_t);
int      pf_pkt_tag     (PF_PKT *, size_t, int, void *);

/* expression API */
PF_EXPR* pf_expr_parse (const char *);
void     pf_expr_free  (PF_EXPR *);
int      pf_expr_eval  (const PF_EXPR *, const PF_PKT *);

#endif	/* _PFORGE_PKT_H_ */
